Skip to content

[EXPORTER] Convert uint64_t attribute values exceeding INT64_MAX to string per OTel spec#4090

Open
thc1006 wants to merge 1 commit into
open-telemetry:mainfrom
thc1006:codehealth/otlp-narrowing-nolint-alias
Open

[EXPORTER] Convert uint64_t attribute values exceeding INT64_MAX to string per OTel spec#4090
thc1006 wants to merge 1 commit into
open-telemetry:mainfrom
thc1006:codehealth/otlp-narrowing-nolint-alias

Conversation

@thc1006
Copy link
Copy Markdown
Contributor

@thc1006 thc1006 commented May 18, 2026

Summary

Per OpenTelemetry attribute type-mapping spec:

Integer values which are within the range of 64 bit signed numbers [-2^63..2^63-1] SHOULD be converted to AnyValue's int_value field.
Integer values which are outside the range of 64 bit signed numbers SHOULD be converted to AnyValue's string_value field using decimal representation.

Pre-PR behavior at the four uint64_t conversion sites in exporters/otlp/src/otlp_populate_attribute_utils.cc implicitly narrowed via // NOLINT(cppcoreguidelines-narrowing-conversions). For uint64_t values exceeding INT64_MAX, this produced negative int_value on the wire — a long-standing spec violation that predates this PR.

This PR replaces the four narrowing call sites with a file-local helper that dispatches per spec:

inline void SetUint64Value(opentelemetry::proto::common::v1::AnyValue *proto_value, uint64_t val)
{
  if (val <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
    proto_value->set_int_value(static_cast<int64_t>(val));
  else
    proto_value->set_string_value(std::to_string(val));
}

Both PopulateAnyValue overloads (for AttributeValue and OwnedAttributeValue) and both shapes (scalar and array element) route through the same helper. Spec-link comment is attached to the helper for future readers.

Scope of fix (4 sites, 1 file)

Site Variant
otlp_populate_attribute_utils.cc:~94 uint64_t scalar in AttributeValue overload
otlp_populate_attribute_utils.cc:~187 nostd::span<const uint64_t> array
otlp_populate_attribute_utils.cc:~254 uint64_t scalar in OwnedAttributeValue overload
otlp_populate_attribute_utils.cc:~331 std::vector<uint64_t> array

Other integer conversions (int, int64_t, unsigned int, uint32_t) always fit in int64_t and were not affected by the spec rule. No other files in exporters/ or sdk/ call set_int_value with uint64_t source (verified via grep).

Tests (new, in otlp_recordable_test.cc)

  1. SetUint64OverflowAsStringPerSpecINT64_MAX + 1string_value with decimal representation
  2. SetUint64BoundaryAsIntPerSpecINT64_MAXint_value (encoding split is val > INT64_MAX)
  3. SetUint64ArrayOverflowAsStringPerSpec — mixed-value array dispatches per element (int + string in same array)

Ratchet

Helper's explicit static_cast is now in a value-guarded branch, so the bugprone-narrowing-conversions diagnostics on these four sites are still silenced.

  • all-options-abiv1-preview warning_limit lowered from 389 to 385
  • all-options-abiv2-preview warning_limit lowered from 395 to 391

Behavior change disclosure

For uint64_t attribute values exceeding INT64_MAX (~9.2e18):

  • Before: wrapped to negative int_value on the wire (non-spec-conformant)
  • After: decimal string in string_value (spec-conformant)

Callers relying on the wrap-to-negative behavior would see breakage. This behavior was never spec-conformant; the new behavior aligns OTLP output with the protocol specification.

Review history

Originally opened as a [CODE HEALTH] PR to fix bugprone-narrowing-conversions warnings via static_cast. @dbarker pointed out in review that the static_cast preserves the spec-violating wrap behavior and asked for spec-compliant string fallback. This PR was then upgraded in scope to the present spec fix.

Test plan

  • CI clang-tidy job passes both abiv1-preview and abiv2-preview at the new limits
  • CI Format job passes (verified locally via clang-format --dry-run --Werror)
  • CI build matrices pass — new tests build and run as part of the OTLP test suite
  • No behavior change for int, int64_t, unsigned int, uint32_t paths

Part of #2053

Copilot AI review requested due to automatic review settings May 18, 2026 13:31
@thc1006 thc1006 requested a review from a team as a code owner May 18, 2026 13:31
@thc1006 thc1006 force-pushed the codehealth/otlp-narrowing-nolint-alias branch from b15a543 to e9fc36b Compare May 18, 2026 13:32
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates OTLP exporter code to align existing clang-tidy suppression comments with the clang-tidy v22 check name, and adjusts CI warning limits accordingly. This is a code health/CI maintenance change intended to keep the clang-tidy ratchet stable after the LLVM/clang-tidy 22 upgrade.

Changes:

  • Renames four NOLINT suppressions in otlp_populate_attribute_utils.cc from the old alias to bugprone-narrowing-conversions.
  • Lowers clang-tidy workflow warning limits for all-options-abiv1-preview and all-options-abiv2-preview.
  • Adds a corresponding CHANGELOG.md entry.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
exporters/otlp/src/otlp_populate_attribute_utils.cc Updates four narrowing-conversion NOLINT suppressions to match clang-tidy v22’s check name.
CHANGELOG.md Adds an Unreleased entry for the code health change.
.github/workflows/clang-tidy.yaml Lowers the warning limits to reflect the reduced warning count.

Comment thread CHANGELOG.md Outdated
@thc1006 thc1006 force-pushed the codehealth/otlp-narrowing-nolint-alias branch from e9fc36b to cc4c581 Compare May 18, 2026 14:16
@thc1006 thc1006 changed the title [CODE HEALTH] Update bugprone-narrowing-conversions NOLINT suppressions in otlp_populate_attribute_utils [CODE HEALTH] Fix clang-tidy narrowing-conversions warnings in otlp_populate_attribute_utils May 18, 2026
@thc1006 thc1006 requested a review from Copilot May 18, 2026 14:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

Comment thread exporters/otlp/src/otlp_populate_attribute_utils.cc Outdated
Comment thread exporters/otlp/src/otlp_populate_attribute_utils.cc Outdated
Comment thread exporters/otlp/src/otlp_populate_attribute_utils.cc Outdated
Comment thread exporters/otlp/src/otlp_populate_attribute_utils.cc Outdated
@thc1006 thc1006 force-pushed the codehealth/otlp-narrowing-nolint-alias branch from cc4c581 to 2c3d074 Compare May 18, 2026 14:32
@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.00%. Comparing base (8fbe81e) to head (8792789).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4090      +/-   ##
==========================================
+ Coverage   82.00%   82.00%   +0.01%     
==========================================
  Files         385      385              
  Lines       16030    16031       +1     
==========================================
+ Hits        13143    13144       +1     
  Misses       2887     2887              
Files with missing lines Coverage Δ
...xporters/otlp/src/otlp_populate_attribute_utils.cc 92.96% <100.00%> (+0.05%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

thc1006 added a commit to thc1006/opentelemetry-cpp that referenced this pull request May 18, 2026
Eliminate the 29 misc-unused-alias-decls warnings flagged by clang-tidy
across 27 files in examples, exporters, sdk, and tests. The most common
pattern was a file-scope `namespace nostd = opentelemetry::nostd;`
declaration that was never referenced via the file-scope alias path
(uses of `nostd::` resolved through the surrounding
OPENTELEMETRY_BEGIN_NAMESPACE namespace nesting instead).

No behavior change. Removed declarations were genuinely dead per clang-tidy.
Where removing an alias affected sibling-line alignment (e.g. `using M = ...`
next to the removed alias), clang-format auto-collapsed the alignment.

Ratchet:
* abiv1-preview warning_limit lowered from 418 to 389
* abiv2-preview warning_limit lowered from 424 to 395

A 30th misc-unused-alias-decls site at
exporters/otlp/src/otlp_populate_attribute_utils.cc:30 is intentionally
not touched in this PR to avoid conflicting with the in-flight open-telemetry#4090.
It can be cleaned up in a follow-up after open-telemetry#4090 lands.

Part of open-telemetry#2053

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
thc1006 added a commit to thc1006/opentelemetry-cpp that referenced this pull request May 18, 2026
Eliminate 29 misc-unused-alias-decls warnings flagged by clang-tidy v22
across 27 files in examples, exporters, sdk, and tests. The dominant
pattern was a file-scope `namespace nostd = opentelemetry::nostd;`
declaration never referenced via the file-scope alias path (uses of
`nostd::` resolved through OPENTELEMETRY_BEGIN_NAMESPACE namespace
nesting instead).

Also remove 4 unused type-alias `using M = std::map<std::string,
std::string>;` declarations in storage tests, observed by Copilot
review. clang-tidy does not flag these (misc-unused-alias-decls targets
only namespace aliases, not type aliases), but they are genuinely dead
code in the same spirit and the same files this PR already touches.

No behavior change. Removed declarations were genuinely unused.
clang-format auto-collapsed adjacent orphan alignment whitespace where
removing a line left aligned siblings.

Ratchet:
* abiv1-preview warning_limit lowered from 418 to 389
* abiv2-preview warning_limit lowered from 424 to 395

A 30th misc-unused-alias-decls site at
exporters/otlp/src/otlp_populate_attribute_utils.cc:30 is intentionally
not touched in this PR to avoid conflicting with the in-flight open-telemetry#4090.
It can be cleaned up in a trivial follow-up after open-telemetry#4090 lands.

Part of open-telemetry#2053

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
thc1006 added a commit to thc1006/opentelemetry-cpp that referenced this pull request May 18, 2026
Eliminate 29 misc-unused-alias-decls warnings flagged by clang-tidy v22
across 27 files in examples, exporters, sdk, and tests. The dominant
pattern was a file-scope `namespace nostd = opentelemetry::nostd;`
declaration never referenced via the file-scope alias path (uses of
`nostd::` resolved through OPENTELEMETRY_BEGIN_NAMESPACE namespace
nesting instead).

Also remove 4 unused type-alias `using M = std::map<std::string,
std::string>;` declarations in storage tests, observed by Copilot
review. clang-tidy does not flag these (misc-unused-alias-decls targets
only namespace aliases, not type aliases), but they are genuinely dead
code in the same spirit and the same files this PR already touches.

No behavior change. Removed declarations were genuinely unused.
clang-format auto-collapsed adjacent orphan alignment whitespace where
removing a line left aligned siblings.

Ratchet:
* abiv1-preview warning_limit lowered from 418 to 389
* abiv2-preview warning_limit lowered from 424 to 395

A 30th misc-unused-alias-decls site at
exporters/otlp/src/otlp_populate_attribute_utils.cc:30 is intentionally
not touched in this PR to avoid conflicting with the in-flight open-telemetry#4090.
It can be cleaned up in a trivial follow-up after open-telemetry#4090 lands.

Part of open-telemetry#2053

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
thc1006 added a commit to thc1006/opentelemetry-cpp that referenced this pull request May 18, 2026
Eliminate 29 misc-unused-alias-decls warnings flagged by clang-tidy v22
across 27 files in examples, exporters, sdk, and tests. The dominant
pattern was a file-scope `namespace nostd = opentelemetry::nostd;`
declaration never referenced via the file-scope alias path (uses of
`nostd::` resolved through OPENTELEMETRY_BEGIN_NAMESPACE namespace
nesting instead).

Also remove 4 unused type-alias `using M = std::map<std::string,
std::string>;` declarations in storage tests, observed by Copilot
review. clang-tidy does not flag these (misc-unused-alias-decls targets
only namespace aliases, not type aliases), but they are genuinely dead
code in the same spirit and the same files this PR already touches.

Also remove 9 now-unused #include directives that IWYU flagged as a
consequence of the alias removals: when an alias like
`namespace http_client = opentelemetry::ext::http::client;` is removed,
the include that brought the namespace into scope is no longer needed.
Same logic for several `opentelemetry/common/attribute_value.h`
includes that supported `namespace common = opentelemetry::common;`
aliases, and `<map>` after removing the unused `using M = ...` from
async_metric_storage_test.cc.

No behavior change. Removed declarations were genuinely unused.
clang-format auto-collapsed adjacent orphan alignment whitespace where
removing a line left aligned siblings.

Ratchet:
* abiv1-preview warning_limit lowered from 418 to 389
* abiv2-preview warning_limit lowered from 424 to 395

A 30th misc-unused-alias-decls site at
exporters/otlp/src/otlp_populate_attribute_utils.cc:30 is intentionally
not touched in this PR to avoid conflicting with the in-flight open-telemetry#4090.
It can be cleaned up in a trivial follow-up after open-telemetry#4090 lands.

Part of open-telemetry#2053

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
@thc1006 thc1006 force-pushed the codehealth/otlp-narrowing-nolint-alias branch from 2c3d074 to 785ec9a Compare May 19, 2026 16:35
@thc1006 thc1006 force-pushed the codehealth/otlp-narrowing-nolint-alias branch from 785ec9a to c77b2ba Compare May 27, 2026 02:10
@thc1006 thc1006 changed the title [CODE HEALTH] Fix clang-tidy narrowing-conversions warnings in otlp_populate_attribute_utils [EXPORTER] Convert uint64_t attribute values exceeding INT64_MAX to string per OTel spec May 27, 2026
…tring per OTel spec

Per OpenTelemetry attribute type-mapping spec (https://opentelemetry.io/
docs/specs/otel/common/attribute-type-mapping/#integer-values), integer
values outside the 64-bit signed range MUST be encoded as AnyValue's
string_value using decimal representation, not wrapped to a negative
int64 via narrowing.

Pre-PR behavior at the four uint64_t conversion sites in
otlp_populate_attribute_utils.cc was to implicitly narrow (suppressed
via NOLINT). For uint64_t values exceeding INT64_MAX, this produced
negative int_value on the wire — a long-standing spec violation that
predates this PR.

This PR fixes the violation via a file-local helper SetUint64Value that
dispatches to set_int_value or set_string_value based on the value's
range. All four uint64_t sites in both PopulateAnyValue overloads now
follow the spec.

Spec-compliance verified by three new tests in otlp_recordable_test.cc:
- UINT64_MAX-equivalent value -> string_value with decimal representation
- INT64_MAX boundary value -> int_value (encoding split is val > INT64_MAX)
- Mixed-value array -> per-element dispatch (int + string in same array)

Side effect: the four bugprone-narrowing-conversions warnings clang-tidy
v22 was reporting are eliminated (the static_cast is now in a guarded
branch, suppressing the diagnostic). Ratchet drops accordingly:
* abiv1-preview warning_limit lowered from 389 to 385
* abiv2-preview warning_limit lowered from 395 to 391

Behavior change: existing callers relying on the wrap-to-negative
behavior for uint64 > INT64_MAX will now see string_value on the wire
instead of negative int_value. This was never spec-conformant; the new
behavior aligns OTLP output with the protocol specification.

Part of open-telemetry#2053

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
@thc1006 thc1006 force-pushed the codehealth/otlp-narrowing-nolint-alias branch from c77b2ba to 8792789 Compare May 27, 2026 03:01
@thc1006 thc1006 requested a review from dbarker May 27, 2026 03:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants